<?php
use think\Validate;
function url($url)
{
    return '/admin/' . $url;
}
if (!function_exists('__')) {

    /**
     * 获取语言变量值
     * @param string $name 语言变量名
     * @param array  $vars 动态变量值
     * @param string $lang 语言
     * @return mixed
     */
    function __($name, $vars = [])
    {
        $r = trans($name);
        return $r ? $r : $name;
    }
}

function getConfig($key = null)
{
    $configs = \think\facade\Cache::get("configs");
    if (!$configs) {
        $configs = \think\facade\Db::name("config")->json(["option_value"])->select()->toArray();
        $configs = array_column($configs, "option_value", "option_name");
        \think\facade\Cache::set("configs", $configs);
    }
    return $key ? $configs[$key] : $configs;
}

function getLangs($key = null)
{
    $langs = [
        1 => 'zh_CN',
        2 => 'en',
    ];
    return $key ? array_search($key, $langs) : $langs;

}

/**
 * 递归方式的对变量中的特殊字符进行转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function addslashesDeep($value)
{
    if (empty($value)) {
        return $value;
    } else {
        return is_array($value) ? array_map('addslashesDeep', $value) : addslashes($value);
    }
}

/**
 * 将对象成员变量或者数组的特殊字符进行转义
 *
 * @access   public
 * @param    mix        $obj      对象或者数组
 * @author   Xuan Yan
 *
 * @return   mix                  对象或者数组
 */
function addslashesDeepObj($obj)
{
    if (is_object($obj) == true) {
        foreach ($obj as $key => $val) {
            $obj->$key = addslashesDeep($val);
        }
    } else {
        $obj = addslashesDeep($obj);
    }

    return $obj;
}

/**
 * 可逆加解密
 * */
function __encode($string, $operation = 'DECODE', $key = 'AIMPHP.COM')
{
    if (empty($string)) {
        return '';
    }

    if (empty($operation)) {
        exit('加密类型未设置');
    }

    $keylength = strlen($key);
    $string    = $operation == 'DECODE' ? base64_decode($string) : $string;
    $coded     = '';
    for ($i = 0; $i < strlen($string); $i += $keylength) {

        $coded .= substr($string, $i, $keylength) ^ $key;

    }

    $coded = $operation == 'ENCODE' ? str_replace('=', '', base64_encode($coded)) : $coded;
    return $coded;
}

/**
 * 递归方式的对变量中的特殊字符去除转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function stripslashesDeep($value)
{
    if (empty($value)) {
        return $value;
    } else {
        return is_array($value) ? array_map('stripslashesDeep', $value) : stripslashes($value);
    }
}

function injectCheck($sql_str)
{
    $r = preg_match('/unhex|drop|truncate|execute|select|insert|update |update%20|delete|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/is', $sql_str);
    return $r;

}

/**
 * 自定义 header 函数，用于过滤可能出现的安全隐患
 * @param   string  string  内容
 * @return  void
 **/
function base_header($string, $replace = true, $http_response_code = 0)
{
    $string = str_replace(array("\r", "\n"), array('', ''), $string);
    if (preg_match('/^\s*location:/is', $string)) {
        @header($string . "\n", $replace);
        exit();
    }
    if (empty($http_response_code) || PHP_VERSION < '4.3') {
        @header($string, $replace);
    } else {
        @header($string, $replace, $http_response_code);
    }
}

/* 加密函数
 * 所有加密均用这个接口，以便修改
 */
function encrypt($char)
{
    return md5(md5($char));
}

/**
 * 获得当前格林威治时间的时间戳
 * @return  integer
 */
function gmtime($date = 0)
{
    if ($date > 0) {
        $today = strtotime(date('Ymd'));
        return $today - ($date - 1) * 24 * 60 * 60;
    }
    //return (time() - date('Z'));
    return time();
}

/*
 * 从html中提取图片整合到数组
@ param string $str
@ return array
 */
function get_pics_from_html($str)
{
    $pattern = "/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.png|\.jpg]))[\'|\"].*?[\/]?>/"; // 正则式
    preg_match_all($pattern, $str, $match);
    return $match[1]; // 返回只带有图片路径的一维数组
}

/*
 * get
 * get方式请求资源
 * @param string $url       基于的baseUrl
 * @return string           返回的资源内容
 */
function file_get($url)
{
    if (function_exists('file_get_contents')) {

        $response = file_get_contents($url);

    } else {

        $ch      = curl_init();
        $timeout = 65;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        $response = curl_exec($ch);
        curl_close($ch);
    }
    return $response;
}

/**
 * post
 * post方式请求资源
 * @param string $url       基于的baseUrl
 * @param array $keysArr    请求的参数列表
 * @param int $flag         标志位
 * @return string           返回的资源内容
 */
function file_post($url, $keysArr, $flag = 0)
{
    $ch = curl_init();
    if (!$flag) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    }

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $keysArr);
    curl_setopt($ch, CURLOPT_URL, $url);
    $ret = curl_exec($ch);

    curl_close($ch);
    return $ret;
}

/*
 * 验证输入的网址
 * @param string  $url:要匹配的网址
 * @param string $base:模型网址，如taobao.com，jd.com
 * @return bool
 */
function is_url($url, $base)
{
    //将网址转换为小写
    if (!empty($base)) {
        $base = strtolower($base);
    }
    //淘宝和天猫，共享域名
    if ($base == 'taobao.com' || $base == 'tmall.com') {
        $base = "(taobao.com)|(tmall.com)";
    }
    $chars = "/((^http)|(^https)):\/\/(\S)+($base)(\S)+/"; //http(https)://***$base***
    if (preg_match($chars, $url)) {
        return true;
    }
    return false;
}

/*
 * 验证手机号格式
 * @param String mobile
 * @return bool
 */
function is_mobile($mobile)
{
    if (preg_match("/^19[0-9]{9}$|^13[0-9]{9}$|^15[0-9]{9}$|^18[0-9]{9}$|^17[0-9]{9}$|^147[0-9]{8}|^811[0-9]{8}$/", $mobile)) {
        return true;
    }
    return false;
}

/**
 * 验证qq号是否正确
 * @5-10位数字
 */
function is_qq($qq)
{
    if (preg_match("/^[0-9]{5,10}$/", $qq)) {
        return true;
    }
    return false;
}

/*
 * 2到20位字符串：只能包括字母、数字、汉字、下划线，且下划线不能开头和结尾
 * @汉字的正则式为(包括全角符号)：\x80-\xff
 */
function is_username($username)
{
    //不能多于16个字符
    if (mb_strlen($username) >= 30) {
        return false;
    }
    if (preg_match("/^[a-zA-Z0-9\x80-\xff]{1}[\_a-zA-Z0-9\x80-\xff]*[a-zA-Z0-9\x80-\xff]{1}$/", $username)) {
        return true;
    }
    return false;
}

/*
 * 检查email是否符合规范
 * param char
 */
function is_email($email)
{
    if (preg_match("/^[0-9a-zA-Z]+(?:[\_\-.][a-z0-9\-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\.[a-zA-Z]+$/i", $email)) {
        return true;
    }
    return false;
}

/*
 * 设置分页
 * @param pageNum：每页显示数，pageNow：当前页，allNum：总条数
 */
function set_page($pageNum = 20, $pageNow = 1, $allNum)
{
    $pages = ceil($allNum / $pageNum); // 总页数

    $GLOBALS['tp']->assign('allNum', $allNum);
    $GLOBALS['tp']->assign('allPages', $pages);

    $arr = array(); //用于返回的数组
    if ($pageNow > $pages || $pageNow < 1 || $pages == 1) // 当前页大于所有页 or 当前页小于1 or 总共只有一页
    {
        return $arr;
    }
    if ($pageNow > 1) // 首页
    {
        $arr[] = array('num' => 1, 'name' => '首页');
        $arr[] = array('num' => $pageNow - 1, 'name' => '«上一页');
    }

    //前3条
    for ($i = $pageNow - 3; $i < $pageNow; $i++) {
        if ($i >= 1) {
            $arr[] = array('num' => $i, 'name' => $i);
        }
    }

    //当前
    $arr[] = array('num' => $pageNow, 'name' => $pageNow);

    //后3条
    $next = $pageNow < 4 ? 7 : $pageNow + 3;
    for ($i = $pageNow + 1; $i <= $next; $i++) {
        if ($i <= $pages) {
            $arr[] = array('num' => $i, 'name' => $i);
        }
    }
    if ($pageNow < $pages) {
        $arr[] = array('num' => $pageNow + 1, 'name' => '下一页»');
        $arr[] = array('num' => $pages, 'name' => '末页');
    }
    return $arr;
}

/* 生成随机数 */
function get_rand_number($len = 6)
{
    /* 选择一个随机的方案 */
    mt_srand((double) microtime() * 1000000);
    return str_pad(mt_rand(1, 999999), $len, '0', STR_PAD_LEFT);
}

/**
 * 生成订单号：2015010112345
 * @return  string
 */
function get_order_sn()
{
    /* 选择一个随机的方案 */
    mt_srand((double) microtime() * 1000000);

    return date('Ymd', gmtime()) . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}

/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取（有可能被伪装）
 * @return mixed
 */
function get_client_ip($type = 0, $adv = false)
{
    $type      = $type ? 1 : 0;
    static $ip = null;
    if ($ip !== null) {
        return $ip[$type];
    }

    if ($adv || is_ali()) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            if (is_weixin()) {
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else {
                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                $pos = array_search('unknown', $arr);
                if (false !== $pos) {
                    unset($arr[$pos]);
                }

                $ip = trim($arr[0]);
            }
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        if (is_weixin()) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            $ip = $ip ? $ip : $_SERVER['REMOTE_ADDR'];
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    }
    //IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/*
 * 淘宝ip地址库获取地址
 */
function get_ip_address_taobao($ip)
{
    $server_api  = 'http://ip.taobao.com/service/getIpInfo.php?ip=';
    $uri         = $server_api . $ip;
    $json_string = file_get($uri);
    $array       = json_decode($json_string, true);
    $ret         = array();
    if ($array['code']) {
        $ret = array(
            'country' => '未知',
            'city'    => '未知',
            'isp'     => '未知',
        );
    } else {
        $ret['region'] = $array['data']['region'] ? $array['data']['region'] : '未知'; //江苏省
        $ret['city']   = $array['data']['city'] ? $array['data']['city'] : '未知'; //徐州市
    }
    return $ret['region'] . ' ' . $ret['city'];
}

/*
 * 新浪ip地址库获取地址
 */
function get_ip_address_sina($ip)
{
    $server_api  = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=';
    $uri         = $server_api . $ip;
    $json_string = file_get($uri);
    $re          = json_decode($json_string);
    return $re->province . ' ' . $re->city;
}

/*
 * 替换字符串中间字符为*
 * @param int start:保留开始几位；int end：保留结束几位；int middle：替换中间几位
 * @return String
 */
function hide_middle($str, $start = 1, $end = 1, $middle)
{
    $length  = mb_strlen($str, 'utf8');
    $replace = "*******************************************"; //用于替换
    $total   = $start + $end;
    if ($length <= $total) {
        return $str;
    }
    //未设置中间保留或强制替换的中间位数大于实际值
    if (!$middle || $middle > $length - $total) {
        $middle = $length - $total;
    }
    return mb_substr($str, 0, $start, 'utf8') . substr($replace, 0, $middle) . mb_substr($str, -$end, $end, 'utf8');
}

/**
 * 格式化时间为：X秒前(后)，X分钟前(后)，X小时前(后)，X天前(后)
 * @param int
 */
function simple_time($time)
{
    $now    = gmtime(); //当前时间
    $value  = $now - $time;
    $dvalue = abs($value);
    if ($dvalue < 60) {
        $r = $dvalue . '秒';
    } else if ($dvalue < 3600) {
        $r = ceil($dvalue / 60) . '分钟';
    } else if ($dvalue < 3600 * 24) {
        $r = ceil($dvalue / 3600) . '小时';
    } else if ($dvalue < 3600 * 24 * 30) {
        $r = ceil($dvalue / (3600 * 24)) . '天';
    } else {
        $r = '30天';
    }
    return $r . ($value > 0 ? '前' : '后');
}

/**
 * 获取当前php文件名
 */
function php_self()
{
    $php_self = substr($_SERVER['PHP_SELF'], strrpos($_SERVER['PHP_SELF'], '/') + 1);
    return $php_self;
}

/**
 * 重写unserialize()函数
 */
function _unserialize($string)
{
    return unserialize(preg_replace('!s:(\d+):"(.*?)";!se', '"s:".strlen("$2").":\"$2\";"', $string));
}

/**
 * 判断当前设备是否是移动设备
 */
function is_mobile_visit()
{
    //如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
        return true;
    }
    //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset($_SERVER['HTTP_VIA'])) {
        //找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
    }
    //脑残法，判断手机发送的客户端标志,兼容性有待提高
    if (isset($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array(
            'nokia',
            'sony',
            'ericsson',
            'mot',
            'samsung',
            'htc',
            'sgh',
            'lg',
            'sharp',
            'sie-',
            'philips',
            'panasonic',
            'alcatel',
            'lenovo',
            'iphone',
            'ipod',
            'blackberry',
            'meizu',
            'android',
            'netfront',
            'symbian',
            'ucweb',
            'windowsce',
            'palm',
            'operamini',
            'operamobi',
            'openwave',
            'nexusone',
            'cldc',
            'midp',
            'wap',
            'mobile',
        );
        //从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return true;
        }
    }
    //协议法，因为有可能不准确，放到最后判断
    if (isset($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return true;
        }
    }
    return false;
}

/*
 * 检查目标文件夹是否存在，如果不存在则自动创建该目录
 * @param       string      folder     目录路径。不能使用相对于网站根目录的URL
 */
function make_dir($folder)
{
    $reval = false;
    if (!file_exists($folder)) {
        /* 如果目录不存在则尝试创建该目录 */
        @umask(0);
        /* 将目录路径拆分成数组 */
        preg_match_all('/([^\/]*)\/?/i', $folder, $atmp);
        /* 如果第一个字符为/则当作物理路径处理 */
        $base = ($atmp[0][0] == '/') ? '/' : '';
        /* 遍历包含路径信息的数组 */
        foreach ($atmp[1] as $val) {
            if ('' != $val) {
                $base .= $val;
                if ('..' == $val || '.' == $val) {
                    /* 如果目录为.或者..则直接补/继续下一个循环 */
                    $base .= '/';
                    continue;
                }
            } else {
                continue;
            }
            $base .= '/';
            if (!file_exists($base)) {
                /* 尝试创建目录，如果创建失败则继续循环 */

                if (mkdir(rtrim($base, '/'), 0777)) {
                    @chmod($base, 0777);
                    $reval = true;
                }
            }
        }
    } else {
        /* 路径已经存在。返回该路径是不是一个目录 */
        $reval = is_dir($folder);
    }
    clearstatcache();
    return $reval;
}

/*
 * 获取32/16位uuid
 */
function guid($length = 32)
{
    mt_srand((double) microtime() * 10000); //optional for php 4.2.0 and up.
    $charid = strtolower(md5(uniqid(rand(), true)));
    if ($length == 16) {
        $charid = substr($charid, 8, 16);
    }

    return $charid;
}

/**
 * html标签-下拉
 * @param  [type]  $ar      [数组key=>val]
 * @param  [type]  $sel     [选中的key值]
 * @param  string  $default [默认一个key值]
 * @param  integer $nav     [显示请选择]
 * @return [string]           [返回html]
 */
function output_select($ar, $sel, $nav = 1)
{
    $r = array();
    if (!is_array($sel) && strpos($sel, ',') !== false) {
        $sel = (array) explode(',', $sel);
    }

    if ($nav) {
        $r[] = "<option value=''>请选择</option>";
    }

    foreach ($ar as $key => $value) {
        $seld = '';
        # code...
        if ((is_array($sel) && in_array($key, $sel)) || (!is_array($sel) && strcmp($sel, $key) == 0)) {
            $seld = 'selected=selected';
        }

        $r[] = '<option value=\'' . $key . '\' ' . $seld . '  >' . $value . '</option>';
    }
    return implode('\n', $r);
}

/**
 * html标签-单选
 * @param  [type]  $name    [元素]
 * @param  [type]  $ar      [数组]
 * @param  [type]  $sel     [选中值]
 * @param  integer $default [默认值]
 * @param  string  $split   [间隔符]
 * @return [type]           [字符]
 */
function output_checkbox($name, $ar, $sel, $split = '')
{
    $r = array();
    foreach ($ar as $key => $value) {
        $seld = '';
        if ($key == $sel) {
            $seld = 'checked=checked';
        }

        $r[] = '<input type="radio" class="" value="' . $key . '" name="' . $name . '" ' . $seld . ' lay-verify="otherReq" title="' . $value . '" />' . $split;

    }
    return implode("\n", $r);
}

/**
 * html标签-多选
 * @param  [type] $name    [元素名]
 * @param  [type] $ar      [数据源]
 * @param  [type] $sel     [选中值]
 * @param  [type] $default [默认选中]
 * @return [type]          [字符]
 */
function output_checkbox_mult($name, $ar, $sel = '')
{
    $r = array();
    if (empty($sel)) {
        $sel = $default;
    }

    foreach ($ar as $key => $value) {
        $seld = '';
        if ($sel && in_array($key, $sel)) {
            $seld = 'checked=checked';
        }

        $r[] = '<input type="checkbox"  value="' . $key . '" name="' . $name . '[]" ' . $seld . '  lay-verify="otherReq" title="' . $value . '"   />';

    }
    return implode("\n", $r);
}

/**
 * 递归生成目录
 * @param  [type] $dir [description]
 * @return [type]      [description]
 */
function mkdirs($dir)
{
    $dir = auto_charset($dir, 'UTF-8', 'GB2312');
    if (!is_dir($dir)) {
        if (!mkdirs(dirname($dir))) {
            return false;
        }
        if (!mkdir($dir, 0777)) {
            return false;
        }
    }
    return true;
}

/**
 * 递归删除目录和文件
 */

function rmdirr($dirname, $keeps = null)
{
    $dirname = auto_charset($dirname, 'UTF-8', 'GB2312');
    if (!file_exists($dirname)) {
        return false;
    }
    if (is_file($dirname) || is_link($dirname)) {
        $kp = 0;
        if ($keeps) {
            foreach ($keeps as $v) {
                if (strpos($dirname, $v) !== false) {
                    $kp = 1;
                    break;
                }
            }
        }
        if ($kp != 1) {
            return unlink($dirname);
        }

    }
    $dir = dir($dirname);
    if ($dir) {
        while (false !== $entry = $dir->read()) {
            if ($entry == '.' || $entry == '..') {
                continue;
            }
            //递归
            rmdirr($dirname . DIRECTORY_SEPARATOR . $entry, $keeps);
        }
    }
    if ($dir) {
        $dir->close();
    }

}

/**
 * 格式化输出文件大小
 */
function formatfilesize($fileSize, $round = 2)
{
    if (empty($fileSize)) {
        return 0;
    }

    $unit = array(' Bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB');
    $i    = 0;
    $inv  = 1 / 1024;
    while ($fileSize >= 1024 && $i < 8) {
        $fileSize *= $inv;
        ++$i;
    }
    $fileSizeTmp = sprintf("%.2f", $fileSize);
    $value       = $fileSizeTmp - (int) $fileSizeTmp ? $fileSizeTmp : $fileSize;
    return round($value, $round) . $unit[$i];
}

// 自动转换字符集 支持数组转换
function auto_charset($fContents, $from = 'gbk', $to = 'utf-8')
{
    $from = strtoupper($from) == 'UTF8' ? 'utf-8' : $from;
    $to   = strtoupper($to) == 'UTF8' ? 'utf-8' : $to;
    if (strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents))) {
        //如果编码相同或者非字符串标量则不转换
        return $fContents;
    }
    if (is_string($fContents)) {
        if (function_exists('mb_convert_encoding')) {
            return mb_convert_encoding($fContents, $to, $from);
        } elseif (function_exists('iconv')) {
            return iconv($from, $to, $fContents);
        } else {
            return $fContents;
        }
    } elseif (is_array($fContents)) {
        foreach ($fContents as $key => $val) {
            $_key             = auto_charset($key, $from, $to);
            $fContents[$_key] = auto_charset($val, $from, $to);
            if ($key != $_key) {
                unset($fContents[$key]);
            }

        }
        return $fContents;
    } else {
        return $fContents;
    }
}

/**
 * curl post data
 * @param  [type] $url  [description]
 * @param  [type] $data [description]
 * @return [type]       [description]
 */
function postData($url, $post_data = array(), $type = 'POST')
{
    $agent = "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; Nibiru H1 Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/5.3.0.80_r701542.440";
    $ch    = curl_init($url);
    if ($type == 'GET') {
        $cookie_file = $_SERVER['DOCUMENT_ROOT'] . __ROOT__ . '/Public/Uploads/curl_cookie/wx___.cookie';
        if (strpos($url, '?') !== false) {
            $split = '&';
        } else {
            $split = '?';
        }
        if ($post_data) {
            $url = rtrim($url, '&') . $split . http_build_query($post_data);
        }

        curl_setopt($ch, CURLOPT_URL, $url);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 获取转向后的内容
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);

    } else {

        $data_string = json_encode($post_data);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 获取转向后的内容
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data_string))
        );

    }
    $result = curl_exec($ch);

    $r = is_not_json($result) ? $result : json_decode($result, true);
    return $r;
}

function is_not_json($str)
{
    return is_null(json_decode($str));
}

/**
 * 显示选中值
 * @param  [type] $arr [数组]
 * @param  [type] $sel [选中值]
 * @return [type]      [字符]
 */
function showSelect($arr, $sel, $split = ',')
{
    if (!isset($sel)) {
        return false;
    }

    if (!is_array($sel) && strpos($sel, ',') !== false) {
        $sels = explode(',', $sel);
    } else {
        $sels = (array) $sel;
    }

    $val = array();
    foreach ($sels as $v) {
        $val[] = $arr[$v];
    }
    return implode($split, $val);
}

/**
 * 数组重组,一对一
 * @param  type  $array       数组
 * @param  type  $key         索引
 * @param  type  $field_value 字段
 * @return type               数组
 */
function array_re_index($array, $key, $field_value = null)
{
    if (empty($array)) {
        return array();
    }

    $new_array = array();
    foreach ($array as $k => $v) {
        if ($v[$key] == '' || is_null($v[$key])) {
            continue;
        }

        if (is_array($field_value)) {
            foreach ($field_value as $k1 => $v1) {
                $index1                   = is_numeric($k1) ? $v1 : $k1;
                $new_array[$v[$key]][$v1] = $v[$index1];
            }
        } elseif (is_string($field_value)) {
            $new_array[$v[$key]] = $v[$field_value];
        } else {
            $new_array[$v[$key]] = $v;
        }
    }
    return $new_array;

}

/**
 * 获取单一字段
 * @return [type] [description]
 */
function getByField($ar, $f, $transform = 'array', $is_string = 0)
{
    $r = array();
    foreach ($ar as $v) {
        if (in_array($v[$f], $r)) {
            continue;
        }

        if (!$v[$f]) {
            continue;
        }

        $r[] = $v[$f];
    }
    if ($transform == 'str') {
        if ($is_string) {
            $r = "'" . implode("','", $r) . "'";
            $r = $r ? $r : -1;
        } else {
            $r = implode(',', $r);
            $r = $r ? $r : -1;
        }
    }
    return $r;
}

/**
 * 获取单一字段
 * @return [type] [description]
 */
function getByFieldStr($ar, $f)
{
    $r = array();
    foreach ($ar as $v) {
        if (in_array($v[$f], $r)) {
            continue;
        }

        if (!$v[$f]) {
            continue;
        }

        $r[] = $v[$f];
    }

    $r = implode("','", $r);
    $r = $r ? "'" . $r . "'" : -1;
    return $r;
}

/**
 * 将表单数组转为数据库查询出的结构形式
 * @param  [type] $form_detail [二维表单]
 * @return [type]              [表记录格式数组]
 */
function post_to_set($form_detail)
{
    if (!$form_detail) {
        return false;
    }

    $new_form_detail = array();
    foreach ($form_detail as $k => $v) {
        foreach ($v as $k1 => $v1) {
            $new_form_detail[$k1][$k] = $v1;

        }

    }
    return $new_form_detail;
}

function getRemoteContent($url, $post = null)
{
    $context = array();
    if (is_array($post)) {
        ksort($post);
        $context['http'] = array(
            'timeout' => 10,
            'method'  => 'POST',
            'content' => http_build_query($post, '', '&'),
        );

    }
    return file_get_contents($url, false, stream_context_create($context));
}

function url_base64_encode($str)
{
    $code = base64_encode($str); //$code='dHQ=';
    $code = str_replace('+', "!", $code); //把所用"+"替换成"!"
    $code = str_replace('/', "*", $code); //把所用"/"替换成"*"
    $code = str_replace('=', "", $code); //把所用"="删除掉
    return $code; //$code='dHQ!'
}
function url_base64_decode($code)
{
    $code = str_replace("!", '+', $code); //把所用"+"替换成"!"
    $code = str_replace("*", '/', $code); //把所用"/"替换成"*"
    $str  = base64_decode($code);
    return $str;
}

/**
 * 显示月份
 * @return [type] [description]
 */
function showMonth($m)
{
    if (!$m) {
        return '';
    }

    if ($m % 12 == 0) {
        return ($m / 12) . '年';
    } else {
        return $m . '个月';
    }
}

//加密函数
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
{
    if (!$string) {
        return;
    }

    // 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
    $ckey_length = 4;

    // 密匙
    $key = md5($key ? $key : 'conqweal');

    // 密匙a会参与加解密
    $keya = md5(substr($key, 0, 16));
    // 密匙b会用来做数据完整性验证
    $keyb = md5(substr($key, 16, 16));
    // 密匙c用于变化生成的密文
    $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) :
        substr(md5(microtime()), -$ckey_length)) : '';
    // 参与运算的密匙
    $cryptkey   = $keya . md5($keya . $keyc);
    $key_length = strlen($cryptkey);
    // 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，
    //解密时会通过这个密匙验证数据完整性
    // 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
    $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) :
    sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);
    $result        = '';
    $box           = range(0, 255);
    $rndkey        = array();
    // 产生密匙簿
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }
    // 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度
    for ($j = $i = 0; $i < 256; $i++) {
        $j       = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp     = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    // 核心加解密部分
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a       = ($a + 1) % 256;
        $j       = ($j + $box[$a]) % 256;
        $tmp     = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        // 从密匙簿得出密匙进行异或，再转成字符
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if ($operation == 'DECODE') {
        // 验证数据有效性，请看未加密明文的格式
        if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
            substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
            return substr($result, 26);
        } else {
            return '';
        }
    } else {
        // 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
        // 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
        return $keyc . str_replace('=', '', base64_encode($result));
    }
}

/**
 * 设置url参数值
 * @param  [type] $url   [description]
 * @param  [type] $key   [description]
 * @param  [type] $value [description]
 * @return [type]        [description]
 */
function setUrl($url, $key, $value)
{
    $a     = explode('?', $url);
    $url_f = $a[0];
    $query = $a[1];
    parse_str($query, $arr);
    if (!$value) {
        unset($arr[$key]);
    } else {
        $arr[$key] = $value;
    }
    return $url_f . '?' . http_build_query($arr);
}

//将内容进行UNICODE编码
function unicode_encode($name)
{
    $name = iconv('UTF-8', 'UCS-2', $name);
    $len  = strlen($name);
    $str  = '';
    for ($i = 0; $i < $len - 1; $i = $i + 2) {
        $c  = $name[$i];
        $c2 = $name[$i + 1];
        if (ord($c) > 0) {
            // 两个字节的文字
            $str .= '\u' . base_convert(ord($c), 10, 16) . base_convert(ord($c2), 10, 16);
        } else {
            $str .= $c2;
        }
    }
    return $str;
}

// 将UNICODE编码后的内容进行解码
function unicode_decode($name)
{
    // 转换编码，将Unicode编码转换成可以浏览的utf-8编码
    $pattern = '/([\w]+)|(\\\u([\w]{4}))/i';
    preg_match_all($pattern, $name, $matches);
    if (!empty($matches)) {
        $name = '';
        for ($j = 0; $j < count($matches[0]); $j++) {
            $str = $matches[0][$j];
            if (strpos($str, '\\u') === 0) {
                $code  = base_convert(substr($str, 2, 2), 16, 10);
                $code2 = base_convert(substr($str, 4), 16, 10);
                $c     = chr($code) . chr($code2);
                $c     = iconv('UCS-2', 'UTF-8', $c);
                $name .= $c;
            } else {
                $name .= $str;
            }
        }
    }
    return $name;
}

/**
 * 获取当前请求的Accept头信息
 * @return string
 */
function getAcceptType($accept = null)
{
    $accept = $accept ? $accept : $_SERVER['HTTP_ACCEPT'];
    $type   = array(
        'html' => 'text/html,application/xhtml+xml',
        'xml'  => 'application/xml,text/xml,application/x-xml',
        'json' => 'application/json,text/x-json,application/jsonrequest,text/json',
        'js'   => 'text/javascript,application/javascript,application/x-javascript',
        'css'  => 'text/css',
        'rss'  => 'application/rss+xml',
        'yaml' => 'application/x-yaml,text/yaml',
        'atom' => 'application/atom+xml',
        'pdf'  => 'application/pdf',
        'text' => 'text/plain',
        'png'  => 'image/png',
        'jpg'  => 'image/jpg,image/jpeg,image/pjpeg',
        'gif'  => 'image/gif',
        'csv'  => 'text/csv',
    );

    foreach ($type as $key => $val) {
        $array = explode(',', $val);
        foreach ((array) $array as $k => $v) {
            if (stristr($accept, $v)) {
                return $key;
            }
        }
    }
    return false;
}

function HandleError($message)
{
    @header("content-type:text/html;charset=utf-8");
    header("HTTP/1.1 500 Internal Server Error");
    echo $message;
    exit;
}

/**
 * 取随机数
 * @param  [type] $length [description]
 * @return [type]         [description]
 */
function randomkeys($length, $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ')
{
    $len = strlen($pattern) - 1;
    for ($i = 0; $i < $length; $i++) {
        $key .= $pattern[mt_rand(0, $len)]; //生成php随机数
    }
    return $key;
}

function get_basename($filename)
{
    return preg_replace('/^.+[\\\\\\/]/', '', $filename);
}

/**
 * 获取url参数
 * @param  [type] $url [description]
 * @param  [type] $key [description]
 * @return [type]      [description]
 */
function getUrl($url, $key)
{
    $a     = explode('?', $url);
    $url_f = $a[0];
    $query = $a[1];
    parse_str($query, $arr);
    return $arr[$key];

}

function userAgent()
{
## This credit must stay intact (Unless you have a deal with @lukasmig or frimerlukas@gmail.com
    ## Made by Lukas Frimer Tholander from Made In Osted Webdesign.
    ## Price will be $2
    $ua           = $_SERVER['HTTP_USER_AGENT'];
    $iphone       = strstr(strtolower($ua), 'mobile'); //Search for 'mobile' in user-agent (iPhone have that)
    $android      = strstr(strtolower($ua), 'android'); //Search for 'android' in user-agent
    $windowsPhone = strstr(strtolower($ua), 'phone'); //Search for 'phone' in user-agent (Windows Phone uses that)

    function androidTablet($ua)
    {
        //Find out if it is a tablet
        if (strstr(strtolower($ua), 'android')) {
            //Search for android in user-agent
            if (!strstr(strtolower($ua), 'mobile')) {
                //If there is no ''mobile' in user-agent (Android have that on their phones, but not tablets)
                return true;
            }
        }
    }
    $androidTablet = androidTablet($ua); //Do androidTablet function
    $ipad          = strstr(strtolower($ua), 'ipad'); //Search for iPad in user-agent

    if ($androidTablet || $ipad) {
        //If it's a tablet (iPad / Android)
        return 'tablet';
    } elseif ($iphone && !$ipad || $android && !$androidTablet || $windowsPhone) {
        //If it's a phone and NOT a tablet
        return 'mobile';
    } else {
        //If it's not a mobile device
        return 'pc';
    }
}

function getIpAddress($ip)
{
    $opts = array(
        'http' => array(
            'method'  => "GET",
            'timeout' => 1, //单位秒
        ),
    );
    $ipContent = file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=" . $ip, false, stream_context_create($opts));
    $r         = json_decode($ipContent, true);
    $ips       = $r['data'];
    return array('province' => $ips['region'], 'city' => $ips['city'], 'country' => $ips['country']);
}

function qCurl($url, $data = array(), $options = [])
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    isset($options['headers']) && curl_setopt($ch, CURLOPT_HTTPHEADER, $options['headers']);
    $timeout = isset($options['timeout']) ?: 3;
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

    if ($data) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //所需
        curl_setopt($ch, CURLOPT_POST, 1);
    }
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function encryx($string, $operation, $key = '')
{
    $key           = md5($key);
    $key_length    = strlen($key);
    $string        = $operation == 'D' ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string;
    $string_length = strlen($string);
    $rndkey        = $box        = array();
    $result        = '';
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($key[$i % $key_length]);
        $box[$i]    = $i;
    }
    for ($j = $i = 0; $i < 256; $i++) {
        $j       = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp     = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a       = ($a + 1) % 256;
        $j       = ($j + $box[$a]) % 256;
        $tmp     = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if ($operation == 'D') {
        if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
            return substr($result, 8);
        } else {
            return '';
        }
    } else {
        return str_replace('=', '', base64_encode($result));
    }
}

//分页
function getPagers($sum)
{
    $href   = $_SERVER['REQUEST_URI'];
    $page   = $_GET['page'];
    $pagers = '<ul> <li><a href="' . setUrl($href, 'page', 1) . '">«</a></li>';

    for ($i = 1; $i <= $sum; $i++) {
        if ($page == $i) {
            $pagers .= '<li class="active"><a>' . $i . '</a></li>';
        } else {

            $pagers .= '<li><a href="' . setUrl($href, 'page', $i) . '">' . $i . '</a></li> ';
        }
    }
    if ($page + 1 < $sum) {
        $pagers .= ' <li><a href="' . setUrl($href, 'page', $page + 1) . '">»</a></li>';
    } else {

        $pagers .= ' <li><a href="' . setUrl($href, 'page', $sum) . '">»</a></li>';
    }
    $pagers .= "</ul>";
    return $pagers;
}

/**
 * 时间差计算
 *
 * @param Timestamp $time
 * @return String Time Elapsed
 * @author Shelley Shyan
 * @copyright http://phparch.cn (Professional PHP Architecture)
 */
function time2Units($time, $format = 'ye:mo:da:ho:mi:se', $expire_str = '0')
{
    if ($time <= 0) {
        return $expire_str;
    }

    $year = floor($time / 60 / 60 / 24 / 365);
    $time -= $year * 60 * 60 * 24 * 365;
    $month = floor($time / 60 / 60 / 24 / 30);
    $time -= $month * 60 * 60 * 24 * 30;
    $day = floor($time / 60 / 60 / 24);
    $time -= $day * 60 * 60 * 24;
    $hour = floor($time / 60 / 60);
    $time -= $hour * 60 * 60;
    $minute = floor($time / 60);
    $time -= $minute * 60;
    $second = $time;
    $elapse = array();

    $unitArr = array(__('year') => 'year', __('month')  => 'month', __('day')     => 'day',
        __('hour')                  => 'hour', __('minute') => 'minute', __('second') => 'second',
    );

    foreach ($unitArr as $cn => $u) {
        if (strpos($format, substr($u, 0, 2)) === false) {
            continue;
        }

        if ($$u > 0) {
            $elapse[] = $$u . $cn;

        }
    }
    return $elapse[0];
}

/**
 * 字符截取
 * @param  [type]  $str     [字符串]
 * @param  integer $start   [开始]
 * @param  [type]  $length  [长度]
 * @param  string  $charset [字符集]
 * @param  string  $suffix  [省略号]
 * @return [type]           [字符]
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = '...')
{
    $str = strip_tags(htmlspecialchars_decode($str));
    $str = str_replace(array("\t", "\n", "&nbsp;"), '', $str);
    if (function_exists("mb_substr")) {
        if ($suffix && strlen($str) > $length) {
            return mb_substr($str, $start, $length, $charset) . $suffix;
        } else {
            return mb_substr($str, $start, $length, $charset);
        }

    } elseif (function_exists('iconv_substr')) {
        if ($suffix && strlen($str) > $length) {
            return iconv_substr($str, $start, $length, $charset) . $suffix;
        } else {
            return iconv_substr($str, $start, $length, $charset);
        }

    }
    $re['utf-8']  = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    preg_match_all($re[$charset], $str, $match);
    $slice = join("", array_slice($match[0], $start, $length));
    if ($suffix) {
        return $slice . $suffix;
    }

    return $slice;
}

function filterImgs($html)
{
    preg_match_all('/<\s*img\s+[^>]*?src\s*=\s*(\'|\")(.*?)\\1[^>]*?\/?\s*>/i', $html, $match);
    return $match[2];
}

//短网址接口
function shorturl($url)
{
    $context = stream_context_create(array(
        'http' => array(
            'timeout' => 1000,
        ),
    ));
    $r = file_get_contents("http://suo.im/api.php?url=" . urlencode($url), 0, $context);
    if ($r) {
        return $r;
    }

    return $url;

}

function html2text($str)
{
    $str = html_entity_decode($str);
    $str = strip_tags($str);
    $str = preg_replace("/<style .*?<\/style>/is", "", $str);
    $str = preg_replace("/<script .*?<\/script>/is", "", $str);
    $str = preg_replace("/<br \s*\/?\/>/i", "\n", $str);
    $str = preg_replace("/<\/?p>/i", "\n\n", $str);
    $str = preg_replace("/<\/?td>/i", "\n", $str);
    $str = preg_replace("/<\/?div>/i", "\n", $str);
    $str = preg_replace("/<\/?blockquote>/i", "\n", $str);
    $str = preg_replace("/<\/?li>/i", "\n", $str);
    $str = preg_replace("/\&nbsp\;/i", " ", $str);
    $str = preg_replace("/\&nbsp/i", " ", $str);
    $str = preg_replace("/\&amp\;/i", "&", $str);
    $str = preg_replace("/\&amp/i", "&", $str);
    $str = preg_replace("/\&lt\;/i", "<", $str);
    $str = preg_replace("/\&lt/i", "<", $str);
    $str = preg_replace("/\&ldquo\;/i", '"', $str);
    $str = preg_replace("/\&ldquo/i", '"', $str);
    $str = preg_replace("/\&lsquo\;/i", "'", $str);
    $str = preg_replace("/\&lsquo/i", "'", $str);
    $str = preg_replace("/\&rsquo\;/i", "'", $str);
    $str = preg_replace("/\&rsquo/i", "'", $str);
    $str = preg_replace("/\&gt\;/i", ">", $str);
    $str = preg_replace("/\&gt/i", ">", $str);
    $str = preg_replace("/\&rdquo\;/i", '"', $str);
    $str = preg_replace("/\&rdquo/i", '"', $str);
    $str = preg_replace("/\n/", '', $str);
    $str = preg_replace("/\t/", ' ', $str);
    $str = preg_replace("/\&\#.*?\;/i", "", $str);
    return $str;
}

function get_rand($proArr)
{
    $result = '';
    //概率数组的总概率精度
    $proSum = array_sum($proArr);
    //概率数组循环
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);
        if ($randNum <= $proCur) {
            $result = $key;
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset($proArr);
    return $result;
}

function is_weixin()
{

    return false;
}

function is_ali()
{

    return false;
}

function get_gps($exifCoord, $banqiu)
{

    $degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;

    $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;

    $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;

    //normalize

    $minutes += 60 * ($degrees - floor($degrees));

    $degrees = floor($degrees);

    $seconds += 60 * ($minutes - floor($minutes));

    $minutes = floor($minutes);

    //extra normalization, probably not necessary unless you get weird data

    if ($seconds >= 60) {

        $minutes += floor($seconds / 60.0);

        $seconds -= 60 * floor($seconds / 60.0);

    }

    if ($minutes >= 60) {

        $degrees += floor($minutes / 60.0);

        $minutes -= 60 * floor($minutes / 60.0);

    }
    $lng_lat = $degrees + $minutes / 60 + $seconds / 60 / 60;
    if (strtoupper($banqiu) == 'W' || strtoupper($banqiu) == 'S') {
        //如果是南半球 或者 西半球 乘以-1
        $lng_lat = $lng_lat * -1;
    }
    return $lng_lat;
    //return array('degrees'=> $degrees, 'minutes'=> $minutes, 'seconds'=> $seconds);
}
/*
取得EXIF的內容
分数 转 小数
 */
function gps2Num($coordPart)
{

    $parts = explode('/', $coordPart);

    if (count($parts) <= 0) {
        return 0;
    }

    if (count($parts) == 1) {
        return $parts[0];
    }

    return floatval($parts[0]) / floatval($parts[1]);

}

//数字显示
function num2show($n)
{
    if ($n > 10000) {
        $r = floor($n / 10000) . 'w+';
    } elseif ($n > 1000) {
        $r = floor($n / 1000) . 'k+';
    } else {
        $r = $n;
    }
    return $r;
}

function to404page()
{
    header("location:/404.html");
    exit;
}

function filterNickname($nickname)
{
    $ar = array('客服', 'admin', 'webmaster', '管理员', '站长');
    $r  = true;
    foreach ($ar as $v) {
        if (strpos($nickname, $v) !== false) {
            $r = false;
            break;
        }
    }
    return $r;
}

//创建后台通知
function createNotice($msg)
{
    $f   = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
    $msg = sprintf("%s,%s,%s", $msg, get_client_ip(), date('Y-m-d H:i:s'));
    file_put_contents(base_path() . '/temp/process/' . $f . '.txt', $msg);
}

function multiSort($ar, $field, $type = 'asc')
{
    if (!$ar) {
        return false;
    }

    $sorts;
    foreach ($ar as $k => $v) {
        $sorts[$k] = $v[$field];
    }
    $sort = $type == 'asc' ? SORT_ASC : SORT_DESC;
    array_multisort($sorts, $sort, $ar);
    return $ar;
}

function getPhoneAddr($phone)
{
    if (!$phone || strlen($phone) != 11) {
        return false;
    }

    $host    = "https://api04.aliyun.venuscn.com";
    $path    = "/mobile";
    $method  = "GET";
    $appcode = "2d615590cf854cf1942b2b4c28220aeb";
    $headers = array();
    array_push($headers, "Authorization:APPCODE " . $appcode);
    $querys = "mobile=" . $phone;
    $bodys  = "";
    $url    = $host . $path . "?" . $querys;

    $curl = curl_init();
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_FAILONERROR, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, false);
    if (1 == strpos("$" . $host, "https://")) {
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    }
    $r    = curl_exec($curl);
    $r    = json_decode($r, true);
    $addr = $r['data']['prov'] . $r['data']['city'];
    return $addr;
}

//文件检查
function fileExistsCheck($url)
{
    $curl = curl_init($url);
    // 不取回数据
    curl_setopt($curl, CURLOPT_NOBODY, true);
    // 发送请求
    $result = curl_exec($curl);
    $found  = false;
    // 如果请求没有发送失败
    if ($result !== false) {
        // 再检查http响应码是否为200
        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        if ($statusCode == 200) {
            $found = true;
        }
    }
    curl_close($curl);
    return $found;
}

//去除https
function removeHttp($url)
{
    return str_replace(array('http:', 'https:'), '', $url);
}

//添加https
function addHttp($url)
{
    if (substr($url, 0, 2) == '//') {
        $url = (IS_HTTPS ? 'https:' : 'http:') . $url;
    }
    return $url;
}

//返回协议头
function httpProtol()
{
    return IS_HTTPS ? 'https://' : 'http://';
}

//设置百分比
function putPct($tag, $pct, $dir)
{
    if (!$tag) {
        return false;
    }

    $d_path = base_path() . '/temp/' . $dir . '/';
    if (!is_dir($d_path)) {
        mkdir($d_path, 0777);
    }

    //检查重复提交
    $f = $d_path . $tag . '.txt';
    file_put_contents($f, $pct);
}

//获取百分比
function getPct($tag, $dir)
{
    $d_path = base_path() . '/temp/' . $dir . '/';
    $f      = $d_path . $tag . '.txt';
    return file_get_contents($f);
}

/**
 * 数组 转 对象
 *
 * @param array $arr 数组
 * @return object
 */
function array_to_object($arr)
{
    if (gettype($arr) != 'array') {
        return;
    }
    foreach ($arr as $k => $v) {
        if (gettype($v) == 'array' || getType($v) == 'object') {
            $arr[$k] = (object) array_to_object($v);
        }
    }

    return (object) $arr;
}

/**
 * 对象 转 数组
 *
 * @param object $obj 对象
 * @return array
 */
function object_to_array($obj)
{
    $obj = (array) $obj;
    foreach ($obj as $k => $v) {
        if (gettype($v) == 'resource') {
            return;
        }
        if (gettype($v) == 'object' || gettype($v) == 'array') {
            $obj[$k] = (array) object_to_array($v);
        }
    }

    return $obj;
}

function dateDiff($part, $begin, $end)
{
    $diff = strtotime($end) - strtotime($begin);
    switch ($part) {
        case "y":$retval = bcdiv($diff, (60 * 60 * 24 * 365));
            break;
        case "m":$retval = bcdiv($diff, (60 * 60 * 24 * 30));
            break;
        case "w":$retval = bcdiv($diff, (60 * 60 * 24 * 7));
            break;
        case "d":$retval = bcdiv($diff, (60 * 60 * 24));
            break;
        case "h":$retval = bcdiv($diff, (60 * 60));
            break;
        case "n":$retval = bcdiv($diff, 60);
            break;
        case "s":$retval = $diff;
            break;
    }
    return $retval;
}

function dateAdd($part, $n, $date)
{
    switch ($part) {
        case "y":$val = date("Y-m-d H:i:s", strtotime($date . " +$n year"));
            break;
        case "m":$val = date("Y-m-d H:i:s", strtotime($date . " +$n month"));
            break;
        case "w":$val = date("Y-m-d H:i:s", strtotime($date . " +$n week"));
            break;
        case "d":$val = date("Y-m-d H:i:s", strtotime($date . " +$n day"));
            break;
        case "h":$val = date("Y-m-d H:i:s", strtotime($date . " +$n hour"));
            break;
        case "n":$val = date("Y-m-d H:i:s", strtotime($date . " +$n minute"));
            break;
        case "s":$val = date("Y-m-d H:i:s", strtotime($date . " +$n second"));
            break;
    }
    return $val;
}

function monthBeginAndEnd()
{
    $year      = date("Y", time());
    $month     = date("m", time());
    $day       = date("d", time());
    $t         = date('t');
    $firstTime = mktime(0, 0, 0, $month, 1, $year);
    $lastTime  = mktime(23, 59, 59, $month, $t, $year);
    return [$firstTime, $lastTime];
}

/**
 * 短网址
 * @param  [type]  $url  [description]
 * @param  integer $type [description]
 * @return [type]        [description]
 */
function bdUrlAPI($url, $type = 1)
{

    if ($type) {
        $baseurl = 'http://dwz.cn/create.php';
    } else {
        $baseurl = 'http://dwz.cn/query.php';
    }

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $baseurl);

    curl_setopt($ch, CURLOPT_POST, true);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    if ($type) {
        $data = array('url' => $url);
    } else {
        $data = array('tinyurl' => $url);
    }

    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $strRes = curl_exec($ch);

    curl_close($ch);

    $arrResponse = json_decode($strRes, true);

    if ($arrResponse['status'] != 0) {

        echo 'ErrorCode: [' . $arrResponse['status'] . '] ErrorMsg: [' . iconv('UTF-8', 'GBK', $arrResponse['err_msg']) . "]<br/>";

        return 0;

    }

    if ($type) {
        return $arrResponse['tinyurl'];
    } else {
        return $arrResponse['longurl'];
    }

}

/**
 * 计算经纬度
 * @param  [type] $lng1 [description]
 * @param  [type] $lat1 [description]
 * @param  [type] $lng2 [description]
 * @param  [type] $lat2 [description]
 * @return [type]       [description]
 */
function getdistance($lng1, $lat1, $lng2, $lat2)
{
    // 将角度转为狐度
    $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a       = $radLat1 - $radLat2;
    $b       = $radLng1 - $radLng2;
    $s       = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
    return $s;
}

function imageCenterCrop($source, $width, $height, $target)
{
    if (!file_exists($source)) {
        return false;
    }

    /* 根据类型载入图像 */
    switch (exif_imagetype($source)) {
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($source);
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng($source);
            break;
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif($source);
            break;
    }
    if (!isset($image)) {
        return false;
    }

    /* 获取图像尺寸信息 */
    $target_w = $width;
    $target_h = $height;
    $source_w = imagesx($image);
    $source_h = imagesy($image);
    /* 计算裁剪宽度和高度 */
    $judge    = (($source_w / $source_h) > ($target_w / $target_h));
    $resize_w = $judge ? ($source_w * $target_h) / $source_h : $target_w;
    $resize_h = !$judge ? ($source_h * $target_w) / $source_w : $target_h;
    $start_x  = $judge ? ($resize_w - $target_w) / 2 : 0;
    $start_y  = !$judge ? ($resize_h - $target_h) / 2 : 0;
    /* 绘制居中缩放图像 */
    $resize_img = imagecreatetruecolor($resize_w, $resize_h);
    imagecopyresampled($resize_img, $image, 0, 0, 0, 0, $resize_w, $resize_h, $source_w, $source_h);
    $target_img = imagecreatetruecolor($target_w, $target_h);
    imagecopy($target_img, $resize_img, 0, 0, $start_x, $start_y, $resize_w, $resize_h);
    /* 将图片保存至文件 */
    if (!file_exists(dirname($target))) {
        mkdir(dirname($target), 0777, true);
    }

    switch (exif_imagetype($source)) {
        case IMAGETYPE_JPEG:
            imagejpeg($target_img, $target);
            break;
        case IMAGETYPE_PNG:
            imagepng($target_img, $target);
            break;
        case IMAGETYPE_GIF:
            imagegif($target_img, $target);
            break;
    }
    return boolval(file_exists($target));
}

/**
 * 导出excel
 * @param  [type] $data   [description]
 * @param  [type] $fields [description]
 * @return [type]         [description]
 */
function exportXls($data, $fields)
{
    ob_clean();
    header('Content-type:application/vnd.ms-excel;');
    header('Content-Disposition:attachment;filename=' . date('YmdHis') . '.xls');
    $title = array_values($fields);
    foreach ($title as $t) {
        echo iconv('UTF-8', 'GB2312', $t) . "\t";
    }
    echo "\n";
    foreach ($data as $d) {
        $item = array();
        foreach ($fields as $f => $v) {
            $item[] = iconv('UTF-8', 'GB2312', $d[$f]);
        }
        echo implode("\t", $item) . "\n";
        sleep(0);
    }
    unset($data, $item, $fields);
    exit;

}

/**
 * in_array升级版
 * @param  [type] $f  原字符
 * @param  [type] $ls 可能包含的字符
 * @return [type]
 */
function in_array_v($f, $ls)
{
    $ff = 0;
    foreach ($ls as $v) {
        if (strpos($f, $v) !== false) {
            $ff = 1;
            break;
        }
    }
    return $ff;
}

function isUrl($s)
{
    return preg_match('/^http[s]?:\/\/' .
        '(([0-9]{1,3}\.){3}[0-9]{1,3}' . // IP形式的URL- 199.194.52.184
        '|' . // 允许IP和DOMAIN（域名）
        '([0-9a-z_!~*\'()-]+\.)*' . // 三级域验证- www.
        '([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.' . // 二级域验证
        '[a-z]{2,6})' . // 顶级域验证.com or .museum
        '(:[0-9]{1,4})?' . // 端口- :80
        '((\/\?)|' . // 如果含有文件对文件部分进行校验
        '(\/[0-9a-zA-Z_!~\*\'\(\)\.;\?:@&=\+\$,%#-\/]*)?)$/',
        $s) == 1;
}

/**
 * 判断是否是蜘蛛访问
 * @return boolean [description]
 */
function isCrawler()
{
    $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
    if (!empty($agent)) {
        $spiderSite = array(
            "TencentTraveler",
            "Baiduspider+",
            "BaiduGame",
            "Googlebot",
            "msnbot",
            "Sosospider+",
            "Sogou web spider",
            "ia_archiver",
            "Yahoo! Slurp",
            "YoudaoBot",
            "Yahoo Slurp",
            "MSNBot",
            "Java (Often spam bot)",
            "BaiDuSpider",
            "Voila",
            "Yandex bot",
            "BSpider",
            "twiceler",
            "Sogou Spider",
            "Speedy Spider",
            "Google AdSense",
            "Heritrix",
            "Python-urllib",
            "Alexa (IA Archiver)",
            "Ask",
            "Exabot",
            "Custo",
            "OutfoxBot/YodaoBot",
            "yacy",
            "SurveyBot",
            "legs",
            "lwp-trivial",
            "Nutch",
            "StackRambler",
            "The web archive (IA Archiver)",
            "Perl tool",
            "MJ12bot",
            "Netcraft",
            "MSIECrawler",
            "WGet tools",
            "larbin",
            "Fish search",
            "360spider",
        );
        foreach ($spiderSite as $val) {
            $str = strtolower($val);
            if (strpos($agent, $str) !== false) {
                return true;
            }
        }
    } else {
        return false;
    }
}

function csv_to_array($filename)
{
    if (!file_exists($filename) || !is_readable($filename) || substr($filename, -4) != '.csv') {
        return false;
    }

    $h = fopen($filename, 'r');
    if ($h) {
        $keys = fgetcsv($h);
        while (!feof($h)) {
            $array[] = array_combine($keys, fgetcsv($h));
        }
        fclose($h);
        return $array;
    }
}

function covert2utf8($str)
{
    if (!empty($str)) {
        $fileType = mb_detect_encoding($str, array('UTF-8', 'GBK', 'LATIN1', 'BIG5', 'GB2312'));
        if ($fileType != 'UTF-8') {
            $str = mb_convert_encoding($str, 'utf-8', $fileType);
        }
    }
    return $str;
}

function https_request($url, $data = null)
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    if (!empty($data)) {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    if (curl_errno() == 0) {
        return json_decode($output, true);

    } else {
        return false;
    }
}

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pid parent标记字段
 * @param string $level level标记字段
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    // 创建Tree
    $tree = array();
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent           = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 将list_to_tree的树还原成列表
 * @param  array $tree  原来的树
 * @param  string $child 孩子节点的键
 * @param  string $order 排序显示的键，一般是主键 升序排列
 * @param  array  $list  过渡用的中间数组，
 * @return array        返回排过序的列表数组
 * @author yangweijie <yangweijiester@gmail.com>
 */
function tree_to_list($tree, $child = '_child', $order = 'id', &$list = array())
{
    if (is_array($tree)) {
        foreach ($tree as $key => $value) {
            $reffer = $value;
            if (isset($reffer[$child])) {
                unset($reffer[$child]);
                tree_to_list($value[$child], $child, $order, $list);
            }
            $list[] = $reffer;
        }
        $list = list_sort_by($list, $order, $sortby = 'asc');
    }
    return $list;
}

/**
 * 获取浏览器信息
 * @param  [type] $glue [true时返回字符，否则数组]
 * @return [type]       [description]
 */
function get_client_browser($glue = null)
{
    $browser = array();
    $agent   = $_SERVER['HTTP_USER_AGENT']; //获取客户端信息

    /* 定义浏览器特性正则表达式 */
    $regex = array(
        'ie'      => '/(MSIE) (\d+\.\d)/',
        'chrome'  => '/(Chrome)\/(\d+\.\d+)/',
        'firefox' => '/(Firefox)\/(\d+\.\d+)/',
        'opera'   => '/(Opera)\/(\d+\.\d+)/',
        'safari'  => '/Version\/(\d+\.\d+\.\d) (Safari)/',
    );
    foreach ($regex as $type => $reg) {
        preg_match($reg, $agent, $data);
        if (!empty($data) && is_array($data)) {
            $browser = $type === 'safari' ? array($data[2], $data[1]) : array($data[1], $data[2]);
            break;
        }
    }
    return empty($browser) ? false : (is_null($glue) ? $browser : implode($glue, $browser));
}

/**
 * 数据XML编码
 * @param mixed $data 数据
 * @return string
 */
function data2xml($data)
{
    if (!$data) {
        return false;
    }

    $xml = '';
    foreach ($data as $key => $value) {
        if (is_int($key)) {
            $xml .= data2xml($value);
        } elseif (is_string($key)) {
            $xml .= "<{$key}>";
            $xml .= is_scalar($value) ? "<![CDATA[{$value}]]>" : data2xml($value);
            $xml .= "</{$key}>";
        }
    }
    return $xml;
}

/**
 * XML数据解码
 * @param  string $xml 原始XML字符串
 * @return array       解码后的数组
 */
function xml2data($xml)
{
    if (!$xml) {
        return false;
    }

    $xml  = new SimpleXMLElement($xml);
    $data = array();
    foreach ($xml as $key => $value) {
        $data[$key] = strval($value);
    }

    return $data;
}

/**
 * 获取完成url
 * @param  [type] $page [description]
 * @return [type]       [description]
 */
function getAppUrl($page = '')
{
    return Request::root(true) . '/' . $page;
}

#----------------项目内公用函数---------#

function checkAccess($rule_id)
{

    $model = \app\admin\model\User::find(session("admin_id"));
    $has   = [];
    foreach ($model->roles as $v) {
        $has = array_merge($v->role->r_auth, $has);
    }

    return in_array($rule_id, $has);
}

/**
 * 日志调试，默认位置public/debug/single.log
 * @param  [type] $param [description]
 * @return [type]        [description]
 */
function debugsys($param)
{
    $info = is_array($param) ? var_export($param, true) : $param;
    $h    = fopen($_SERVER['DOCUMENT_ROOT'] . '/debug.txt', 'a');
    fwrite($h, $info);
    fclose($h);
}

function splitWords($keywords)
{
    if (strtolower(substr(PHP_OS, 0, 3)) == 'win') {
        return $keywords;
    }
    $fpath = base_path()() . 'extend/scws';
    $so    = scws_new();
    $so->set_charset('utf-8');
    $so->add_dict($fpath . '/dict.utf8.xdb');
    $so->set_rule($fpath . '/rules.utf8.ini');
    $so->set_ignore(true);
    $so->set_multi(false);
    $so->set_duality(false);
    $so->send_text($keywords);
    $words   = [];
    $results = $so->get_tops(8);
    $res;
    foreach ($results as $key => $value) {
        $res[] = $value['word'];
    }
    return $res ? implode(',', $res) : '';
}

/**
 * 创建网址
 * @return [type] [description]
 */
function createUrl($type, $title, $id)
{

    $df = [
        'task' => "%s-t%d",
        'art'  => "%s-a%d",
    ];

    preg_match("/[\x7f-\xff]/", $title) && $title = Pinyin($title);

    $title = html_entity_decode($title, ENT_QUOTES);
    if (!$title) {
        return '';
    }

    $title = preg_replace_callback("/[:\s&%x*#?\.,°'\/]+/is", function ($v) {
        return '-';
    }, $title);
    $title = strtolower($title);

    $title = msubstr($title, 0, 20, 'utf-8', '');
    return sprintf($df[$type], $title, $id);
}

function getFirstCharter($str)
{
    if (empty($str)) {return '';}
    $fchar = ord($str{0});
    if ($fchar >= ord('A') && $fchar <= ord('z')) {
        return strtoupper($str{0});
    }

    $s1  = iconv('', 'gb2312', $str);
    $s2  = iconv('', 'UTF-8', $s1);
    $s   = $s2 == $str ? $s1 : $str;
    $asc = ord($s{0}) * 256 + ord($s{1}) - 65536;
    if ($asc >= -20319 && $asc <= -20284) {
        return 'A';
    }

    if ($asc >= -20283 && $asc <= -19776) {
        return 'B';
    }

    if ($asc >= -19775 && $asc <= -19219) {
        return 'C';
    }

    if ($asc >= -19218 && $asc <= -18711) {
        return 'D';
    }

    if ($asc >= -18710 && $asc <= -18527) {
        return 'E';
    }

    if ($asc >= -18526 && $asc <= -18240) {
        return 'F';
    }

    if ($asc >= -18239 && $asc <= -17923) {
        return 'G';
    }

    if ($asc >= -17922 && $asc <= -17418) {
        return 'H';
    }

    if ($asc >= -17417 && $asc <= -16475) {
        return 'J';
    }

    if ($asc >= -16474 && $asc <= -16213) {
        return 'K';
    }

    if ($asc >= -16212 && $asc <= -15641) {
        return 'L';
    }

    if ($asc >= -15640 && $asc <= -15166) {
        return 'M';
    }

    if ($asc >= -15165 && $asc <= -14923) {
        return 'N';
    }

    if ($asc >= -14922 && $asc <= -14915) {
        return 'O';
    }

    if ($asc >= -14914 && $asc <= -14631) {
        return 'P';
    }

    if ($asc >= -14630 && $asc <= -14150) {
        return 'Q';
    }

    if ($asc >= -14149 && $asc <= -14091) {
        return 'R';
    }

    if ($asc >= -14090 && $asc <= -13319) {
        return 'S';
    }

    if ($asc >= -13318 && $asc <= -12839) {
        return 'T';
    }

    if ($asc >= -12838 && $asc <= -12557) {
        return 'W';
    }

    if ($asc >= -12556 && $asc <= -11848) {
        return 'X';
    }

    if ($asc >= -11847 && $asc <= -11056) {
        return 'Y';
    }

    if ($asc >= -11055 && $asc <= -10247) {
        return 'Z';
    }

    return null;
}

function Pinyin($zh)
{
    $ret = "";
    $s1  = iconv("UTF-8", "gb2312", $zh);
    $s2  = iconv("gb2312", "UTF-8", $s1);
    if ($s2 == $zh) {$zh = $s1;}
    for ($i = 0; $i < strlen($zh); $i++) {
        $s1 = substr($zh, $i, 1);
        $p  = ord($s1);
        if ($p > 160) {
            $s2 = substr($zh, $i++, 2);
            $ret .= getFirstCharter($s2);
        } else {
            $ret .= $s1;
        }
    }
    return strtolower($ret);
}

if (!function_exists('validate')) {
    /**
     * 生成验证对象
     * @param string|array $validate      验证器类名或者验证规则数组
     * @param array        $message       错误提示信息
     * @param bool         $batch         是否批量验证
     * @param bool         $failException 是否抛出异常
     * @return Validate
     */
    function validate($validate = '', array $message = [], bool $batch = false, bool $failException = true): Validate
    {
        if (is_array($validate) || '' === $validate) {
            $v = new Validate();
            if (is_array($validate)) {
                $v->rule($validate);
            }
        } else {

            if (strpos($validate, '.')) {
                // 支持场景
                [$validate, $scene] = explode('.', $validate);
            }

            $class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate);

            $v = new $class();

            if (!empty($scene)) {
                $v->scene($scene);
            }
        }

        return $v->message($message)->batch($batch)->failException($failException);
    }
}
